#include "gcpch.h"
#include "gui_globals.h"
#include "gui_listpane.h"
#include "diritem.h"
#include "attributes.h"
#include "gui_styleset.h"
#include "virtdir_filesystem.h"

#include <io.h>

static ATOM g_listpane_class_atom = 0;

static void clear_globals()
{
    g_listpane_class_atom = 0;
}

static void listpane_paint(geek_gui_listpane *pane)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(pane->hwnd,&ps);
    RECT rc;
    RECT client_rc;

    GetClientRect(pane->hwnd,&client_rc);

    SelectObject(hdc,geek_gui_styles->font_listpane_items.hfont);

    geek_diritem items[128];
    int count = geek_virtdir_processor_get_items(&pane->proc,0,sizeof(items)/sizeof(items[0]),items);

    int y = 0;
    for(geek_diritem *citem = items; citem < items + count; ++citem)
    {
        rc.left = 0;
        rc.right = client_rc.right;
        rc.top = y;
        rc.bottom = y + 16;
        DrawTextEx(
            hdc,
            citem->display_name,
            -1,
            &rc,
            DT_NOPREFIX,
            NULL
            );

        y += 16;
    }

    EndPaint(pane->hwnd,&ps);
}

static LRESULT CALLBACK listpane_wndproc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    )
{
    geek_gui_listpane *listpane = reinterpret_cast<geek_gui_listpane *>(GetWindowLongPtr(hWnd,GWLP_USERDATA));
    
    if(listpane == NULL && uMsg != WM_NCCREATE)
    {
        return DefWindowProc(hWnd,uMsg,wParam,lParam);
    }

    switch(uMsg)
    {
    case WM_NCCREATE:
        SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)((CREATESTRUCT *)lParam)->lpCreateParams);
        break;
    case WM_PAINT:
        listpane_paint(listpane);
        return 0;
    }

    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

static bool register_listpane_class()
{
    WNDCLASSEX wcex;
    memset(&wcex,0,sizeof(wcex));

    wcex.cbSize = sizeof(wcex);
    wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
    wcex.hInstance = geek_gui_geekcmd_hinstance;
    wcex.lpfnWndProc = &listpane_wndproc;
    wcex.lpszClassName = L"GEEKCMD_LISTPANE";
    wcex.style = CS_HREDRAW|CS_VREDRAW;
    wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

    g_listpane_class_atom = RegisterClassEx(&wcex);
    return g_listpane_class_atom != 0;
}

bool geek_gui_listpane_init()
{
    clear_globals();
    return register_listpane_class();
}

void geek_gui_listpane_deinit()
{
    if(g_listpane_class_atom != 0)
    {
        UnregisterClass((LPCWSTR)g_listpane_class_atom,geek_gui_geekcmd_hinstance);
    }

    clear_globals();
}

bool geek_gui_listpane_create(geek_gui_listpane *pane, HWND parent)
{
    memset(pane,0,sizeof(geek_gui_listpane));

    if(!geek_virtdir_processor_create(&pane->proc))
    {
        goto error_exit;
    }

    if(!geek_virtdir_filesystem_create(&pane->proc,&pane->virtdir.virtdir))
    {
        goto error_exit;
    }

    pane->hwnd = CreateWindowEx(
        WS_EX_STATICEDGE,
        (LPCWSTR)g_listpane_class_atom,
        NULL,
        WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE,
        0,
        0,
        100,
        100,
        parent,
        NULL,
        geek_gui_geekcmd_hinstance,
        pane
        );

    if(pane->hwnd == NULL)
    {
        goto error_exit;
    }

    pane->proc.listpane = pane;

    (*pane->virtdir.virtdir.navigate_fn)(&pane->virtdir.virtdir,L"d:\\__kompleks\\docs\\Java");

    return true;

error_exit:
    geek_gui_listpane_destroy(pane);
    return false;
}

void geek_gui_listpane_destroy(geek_gui_listpane *pane)
{
    pane->proc.listpane = NULL;

    if(pane->hwnd != NULL)
    {
        DestroyWindow(pane->hwnd);
    }

    geek_virtdir_processor_destroy(&pane->proc);

    memset(pane,0,sizeof(geek_gui_listpane));
}

void geek_gui_listpane_refresh(geek_gui_listpane *pane)
{
    InvalidateRect(pane->hwnd,NULL,FALSE);
}
